实现卡片无限滚动动画 您所在的位置:网站首页 uicollectionview 横向卡片 实现卡片无限滚动动画

实现卡片无限滚动动画

#实现卡片无限滚动动画| 来源: 网络整理| 查看: 265

概要设计:

设置css的animation在适当的时间点重置动画来现实视觉上无限滚动的效果。

详细设计: 计算动画中所需预设的卡片dom节点个数(即视觉上最多能看到的卡片个数),如图1视窗高度为120px,卡片高度为56px,上下margin均为24px,因此一张卡片最多占据56+24*2=104px。当卡片处于视窗垂直居中的位置时,卡片上下各有(120-104)/2 = 8px的高度来承载其余卡片,因此所需预设卡片dom节点个数为3个。

(图1) (图2)

设置动画的运动轨迹和持续时间来达到视觉上循环滚动的效果。如图3初始状态下第一张卡片位置处于距离视窗顶部24px的位置,当第二张卡片运动到距离视窗顶部24px的位置时重置动画即可达到视觉上连续滚动的效果。计算卡片需要向上滚动的公式为【初始距顶部距离 - 目标距顶部距离】即56+24*2-24=80px,因此设置动画帧的目标位置为transform: translateY(-80px)。

代码实现:

点五已获得500元京东卡 import { defineComponent } from "vue"; export default defineComponent({ setup() {}, }); .wrapper { height: 500px; display: flex; align-items: center; justify-content: center; } .container { width: 300px; height: 120px; overflow: hidden; background: #ccc; } .content { width: 290px; height: 56px; display: flex; margin: 24px auto; background: #fff; border-radius: 100px; flex-flow: row nowrap; align-items: center; backdrop-filter: blur(4px); animation: scroll 3s linear 1s infinite; } .image { width: 36px; height: 36px; margin: auto 10px; border-radius: 100%; } span { font-family: PingFang SC; font-size: 20px; line-height: 20px; text-align: center; } @keyframes scroll { from { transform: translateY(0); } to { transform: translateY(-80px); } }

效果展示:

进阶功能:

动态更新卡片的数据

功能分析:

卡片仍保持无限滚动,但每张卡片展示的数据均不同,也就是说滚动时视窗内的dom节点不是每次都相同的。

概要设计:

基于上述功能分析由此可以衍生出两个设计思路:

展示多少条数据就渲染多少个dom节点,简单粗暴无需考虑动态更新数据问题;当数据量大时会导致页面性能变差,除非数据量较少否则不推荐。 固定dom节点数,在dom节点移动到视窗之外即进行数据更新;需保证修改dom节点时不会导致视窗内的卡片闪烁;(采纳) 详细设计: 根据当前视窗宽高以及卡片宽高,设置六个卡片dom节点,并将每三张卡片分一个块,这里分两个块为card1、card2(如下图)。

将两个块的位置重叠(为了方便设计动画),card2向上移动(56+24)*3=240px的距离。

计算card2动画需要延迟执行的时间。这里我设置每个card块动画移动距离为480px,执行时间为12s,那么card2延迟执行的时间公示为【延迟距离(card高度)/速度】即240/480/12 = 6s。所以动画帧设置为 @keyframes scroll1 { from { transform: translateY(0); left: 0; } to { transform: translateY(-480px); } } @keyframes scroll2 { from { transform: translateY(-240px); left: 0; } to { transform: translateY(-720px); } } .test1 { animation: scroll1 12s linear 0s infinite; margin-top: 120px; } .test2 { animation: scroll2 12s linear 6s infinite; transform: translateY(-240px); } 监听card块,当card块移出视窗时,触发dom节点刷新。监听使用IntersectionObserver这个api。 @keyframes scroll1 { from { transform: translateY(0); left: 0; } to { transform: translateY(-480px); } } @keyframes scroll2 { from { transform: translateY(-240px); left: 0; } to { transform: translateY(-720px); } } .test1 { animation: scroll1 12s linear 0s infinite; margin-top: 120px; } .test2 { animation: scroll2 12s linear 6s infinite; transform: translateY(-240px); }

以下为完整代码:

{{ item }}已获得500元京东卡 {{ item }}已获得100元京东卡 import { ref, defineComponent, onMounted } from "vue"; export default defineComponent({ setup() { let firsrObserver = true; let data: any = []; for (let i = 1; i { if (currentIndex + 3 { // 第三第四第五加载新数据 if (!entry[0].isIntersecting) { console.log(entry); if (entry[0].target.id === "card1") { cardArr1.value.splice(0, 3, ...getNewData()); } else { cardArr2.value.splice(0, 3, ...getNewData()); } console.log(cardArr1.value, cardArr2.value); } firsrObserver = false; }); onMounted(() => { observer2.observe(document.getElementById("card1") as HTMLElement); observer2.observe(document.getElementById("card2") as HTMLElement); }); return { data, cardArr1, cardArr2, }; }, }); .wrapper { height: 500px; display: flex; align-items: center; /* background: pink; */ justify-content: center; } .container { width: 300px; height: 120px; overflow: hidden; background: #ccc; } .test1 { animation: scroll1 12s linear 0s infinite; margin-top: 120px; } .test2 { animation: scroll2 12s linear 6s infinite; transform: translateY(-240px); } .content { width: 290px; height: 56px; display: flex; margin: 24px auto; background: #fff; border-radius: 100px; flex-flow: row nowrap; align-items: center; backdrop-filter: blur(4px); } .image { width: 36px; height: 36px; margin: auto 10px; border-radius: 100%; } span { font-family: PingFang SC; font-size: 20px; line-height: 20px; text-align: center; } @keyframes scroll1 { from { transform: translateY(0); left: 0; } to { transform: translateY(-480px); } } @keyframes scroll2 { from { transform: translateY(-240px); left: 0; } to { transform: translateY(-720px); } }

效果展示:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有